﻿using Nito.AsyncEx;
using System.Threading;
using Volo.Abp.DependencyInjection;

namespace PLCS.Domain.Tasks;

public class TaskManager : ISingletonDependency
{
    private readonly IHisTaskRepository _hisTaskRepository;
    private readonly ITaskRepository _taskRepository;
    private static AsyncLock _asyncLock = new();
    private static AsyncLock _asyntaskIdcLock = new();
    private int _taskIdCounter = 0;

    public TaskManager(IHisTaskRepository hisTaskRepository, ITaskRepository taskRepository)
    {
        _hisTaskRepository = hisTaskRepository;
        _taskRepository = taskRepository;
    }

    public async Task<int> GetTaskIdAsync()
    {
        using (await _asyntaskIdcLock.LockAsync())
        {
            if (_taskIdCounter == 0)
                _taskIdCounter = await InitalTaskIdAsync();
            return _taskIdCounter;
        }
    }

    public async Task<int> InitalTaskIdAsync()
    {
        long histaskCount = await _hisTaskRepository.GetCountAsync();
        long taskCount = await _taskRepository.GetCountAsync();
        long count = histaskCount + taskCount;
        var lastTask = await _taskRepository.GetLastTaskAsync();
        var lastHisTask = await _hisTaskRepository.GetLastTaskAsync();
        if (lastTask != null)
        {
            if (count <= lastTask.TaskId)
                count = lastTask.TaskId;
        }
        else
        {
            if (lastHisTask != null)
            {
                if (count <= lastHisTask.TaskId)
                    count = lastHisTask.TaskId;
            }
        }

        return (int)count + 1;
    }

    public async Task<int> InsertAsync(TaskModel model)
    {
        using (await _asyncLock.LockAsync())
        {
            if (_taskIdCounter == 0)
                _taskIdCounter = await InitalTaskIdAsync();
            model.TaskId = _taskIdCounter++;
            await _taskRepository.InsertAsync(model);
            return model.TaskId;
        }
    }
}